home *** CD-ROM | disk | FTP | other *** search
/ PD Collection CD 1 / PD Collection CD 1.iso / textual / tex / files / !tex / TeXsource / commontex / c / align next >
Encoding:
Text File  |  1988-04-18  |  25.4 KB  |  677 lines

  1. /*
  2.  *    Copyright 1986, 1987 Pat Joseph Monardo. All rights reserved.
  3.  *    Copying of this file is granted according to the provisions 
  4.  *    specified in the file COPYING which must accompany this file.
  5.  */
  6.  
  7.  
  8. /*
  9.  *              align.c
  10.  */
  11.  
  12. #include "tex.h"
  13. #include "cmds.h"
  14. #include "heap.h"
  15. #include "arith.h"
  16. #include "eq.h"
  17. #include "eqstack.h"
  18. #include "hash.h"
  19. #include "token.h"
  20. #include "tokenstack.h"
  21. #include "scan.h"
  22. #include "evalstack.h"
  23. #include "box.h"
  24. #include "pack.h"
  25. #include "math.h"
  26. #include "mlisthlist.h"
  27. #include "error.h"
  28. #include "align.h"
  29.  
  30. ptr             align_ptr;
  31.  
  32. ptr             cur_align;
  33. ptr             cur_span;
  34. ptr             cur_loop;
  35. ptr             cur_head;
  36. ptr             cur_tail;
  37.  
  38. push_alignment ()
  39. {
  40.         ptr             p;
  41.  
  42.         p = get_node(ALIGN_STACK_NODE_SIZE);
  43.         link(p) = align_ptr;
  44.         info(p) = cur_align;
  45.         llink(p) = preamble;
  46.         rlink(p) = cur_span;
  47.         mem[p + 2].i = cur_loop;
  48.         mem[p + 3].i = align_state;
  49.         info(p + 4) = cur_head;
  50.         link(p + 4) = cur_tail;
  51.         align_ptr = p;
  52.         cur_head = get_avail();
  53. }
  54.  
  55. pop_alignment ()
  56. {
  57.         ptr             p;
  58.  
  59.         free_avail(cur_head);
  60.         p = align_ptr;
  61.         cur_tail = link(p + 4);
  62.         cur_head = info(p + 4);
  63.         align_state = mem[p + 3].i;
  64.         cur_loop = mem[p + 2].i;
  65.         cur_span = rlink(p);
  66.         preamble = llink(p);
  67.         cur_align = info(p);
  68.         align_ptr = link(p);
  69.         free_node(p, ALIGN_STACK_NODE_SIZE);
  70. }
  71.  
  72. init_align ()
  73. {
  74.         ptr             p;
  75.         ptr             save_cs_ptr;
  76.         
  77.         save_cs_ptr = cur_cs;
  78.         push_alignment();
  79.         align_state = -1000000;
  80.         if (mode == MMODE && (tail != head || incompleat_noad != NULL)) {
  81.                 print_err("Improper ");
  82.                 print_esc("halign");
  83.                 print(" inside $$'s");
  84.                 help_display_align();
  85.                 error();
  86.                 flush_math();
  87.         }
  88.         push_nest();
  89.         if (mode == MMODE) {
  90.                 mode = -VMODE;
  91.                 prev_depth = nest[nest_ptr - 2].aux_field;
  92.         } else if (mode > 0)
  93.                 negate(mode);
  94.         scan_spec();
  95.         new_save_level(ALIGN_GROUP);
  96.         preamble = NULL;
  97.         cur_align = align_head;
  98.         cur_loop = NULL;
  99.         scanner_status = ALIGNING;
  100.         warning_index = save_cs_ptr;
  101.         align_state = -1000000;
  102.         loop {
  103.                 link(cur_align) = new_param_glue(TAB_SKIP_CODE);
  104.                 cur_align = link(cur_align);
  105.                 if (cur_cmd == CAR_RET)
  106.                         break;
  107.                 p = align_tokens;
  108.                 token_link(p) = NULL;
  109.                 loop {
  110.                         get_preamble_token();
  111.                         if (cur_cmd == MAC_PARAM)
  112.                                 break;
  113.                         if (cur_cmd <= CAR_RET &&
  114.                                 cur_cmd >= TAB_MARK &&
  115.                                 align_state == -1000000) {
  116.                                 if (p == align_tokens &&
  117.                                         cur_loop == NULL &&
  118.                                         cur_cmd == TAB_MARK) {
  119.                                         cur_loop = cur_align;
  120.                                 } else {
  121.                                         print_err("Missing # inserted in alignment preamble");
  122.                                         help_preamble_missing();
  123.                                         back_error();
  124.                                         break;
  125.                                 }
  126.                         } else if (cur_cmd != SPACER || p != align_tokens) {
  127.                                 token_link(p) = new_token();
  128.                                 p = token_link(p);
  129.                                 token(p) = cur_tok;
  130.                         }
  131.                 }
  132.                 link(cur_align) = new_null_box();
  133.                 cur_align = link(cur_align);
  134.                 info(cur_align) = end_span;
  135.                 width(cur_align) = NULL_FLAG;
  136.                 u_part(cur_align) = token_link(align_tokens);
  137.                 p = align_tokens;
  138.                 token_link(p) = NULL;
  139.                 loop {
  140.                         get_preamble_token();
  141.                         if (cur_cmd <= CAR_RET &&
  142.                                 cur_cmd >= TAB_MARK &&
  143.                                 align_state == -1000000)
  144.                                 break;
  145.                         if (cur_cmd == MAC_PARAM) {
  146.                                 print_err("Only one # is allowed per tab");
  147.                                 help_preamble_many();
  148.                                 error();
  149.                                 continue;
  150.                         }
  151.                         token_link(p) = new_token();
  152.                         p = token_link(p);
  153.                         token(p) = cur_tok;
  154.                 }
  155.                 token_link(p) = new_token();
  156.                 p = token_link(p);
  157.                 token(p) = END_TEMPLATE_TOKEN;
  158.                 v_part(cur_align) = token_link(align_tokens);
  159.         }
  160.         scanner_status = NORMAL;
  161.         new_save_level(ALIGN_GROUP);
  162.         if (every_cr != NULL)
  163.                 begin_token_list(every_cr, EVERY_CR_TEXT);
  164.         align_peek();
  165. }
  166.  
  167. get_preamble_token ()
  168. {
  169. restart:
  170.         get_token();
  171.         while (cur_chr == SPAN_CODE && cur_cmd == TAB_MARK) {
  172.                 get_token();
  173.                 if (cur_cmd > MAX_COMMAND) {
  174.                         expand();
  175.                         get_token();
  176.                 }
  177.         }
  178.         if (cur_cmd == ASSIGN_GLUE && cur_chr == GLUE_BASE + TAB_SKIP_CODE) {
  179.                 scan_optional_equals();
  180.                 scan_glue(GLUE_VAL);
  181.                 if (global_defs > 0)
  182.                         geq_define(GLUE_BASE + TAB_SKIP_CODE, GLUE_REF, (ptr) cur_val);
  183.                 else eq_define(GLUE_BASE + TAB_SKIP_CODE, GLUE_REF, (ptr) cur_val);
  184.                 goto restart;
  185.         }
  186. }
  187.  
  188. align_peek ()
  189. {
  190. restart:
  191.         align_state = 1000000;
  192.         get_nbx_token();
  193.         if (cur_cmd == NO_ALIGN) {
  194.                 scan_left_brace();
  195.                 new_save_level(NO_ALIGN_GROUP);
  196.                 if (mode == -VMODE)
  197.                         normal_paragraph();
  198.         } else if (cur_cmd == RIGHT_BRACE)
  199.                 fin_align();
  200.         else if (cur_cmd == CAR_RET && cur_chr == CR_CR_CODE)
  201.                 goto restart;
  202.         else {
  203.                 init_row();
  204.                 init_col();
  205.         }
  206. }
  207.  
  208. init_row()
  209. {
  210.         push_nest();
  211.         mode = (-HMODE - VMODE) - mode;
  212.         aux = 0;
  213.         tail_append(new_glue(glue_ptr(preamble)));
  214.         subtype(tail) = TAB_SKIP_CODE + 1;
  215.         cur_align = link(preamble);
  216.         cur_tail = cur_head;
  217.         init_span(cur_align);
  218. }
  219.  
  220. init_span (p)
  221.         ptr             p;
  222. {
  223.         push_nest();
  224.         if (mode == -HMODE)
  225.                 space_factor = 1000;
  226.         else {
  227.                 prev_depth = IGNORE_DEPTH;
  228.                 normal_paragraph();
  229.         }
  230.         cur_span = p;
  231. }
  232.  
  233. init_col ()
  234. {
  235.         extra_info(cur_align) = cur_cmd;
  236.         if (cur_cmd == OMIT)
  237.                 align_state = 0;
  238.         else {
  239.                 back_input();
  240.                 begin_token_list((ptr) u_part(cur_align), (qword) U_TEMPLATE);
  241.         }
  242. }
  243.  
  244. bool
  245. fin_col ()
  246. {
  247.         hword   n;
  248.         gord    o;
  249.         ptr             p;
  250.         ptr             q;
  251.         ptr             r;
  252.         ptr             s;
  253.         ptr             u;
  254.         scal    w;
  255.  
  256.         q = link(cur_align);
  257.         if (cur_align == NULL || q == NULL)
  258.                 confusion("endv");
  259.         p = link(q);
  260.         if (p == NULL && extra_info(cur_align) < CR_CODE) {
  261.                 if (cur_loop != NULL) {
  262.                         link(q) = new_null_box();
  263.                         p = link(q);
  264.                         info(p) = end_span;
  265.                         width(p) = NULL_FLAG;
  266.                         cur_loop = link(cur_loop);
  267.                         q = align_tokens;
  268.                         r = u_part(cur_loop);
  269.                         while (r != NULL) {
  270.                                 token_link(q) = new_token();
  271.                                 q = token_link(q);
  272.                                 token(q) = token(r);
  273.                                 r = token_link(r);
  274.                         }
  275.                         token_link(q) = NULL;
  276.                         u_part(p) = token_link(align_tokens);
  277.                         q = align_tokens;
  278.                         r = v_part(cur_loop);
  279.                         while (r != NULL) {
  280.                                 token_link(q) = new_token();
  281.                                 q = token_link(q);
  282.                                 token(q) = token(r);
  283.                                 r = token_link(r);
  284.                         }
  285.                         token_link(q) = NULL;
  286.                         v_part(p) = token_link(align_tokens);
  287.                         cur_loop = link(cur_loop);
  288.                         link(p) = new_glue(glue_ptr(cur_loop));
  289.                 } else {
  290.                         print_err("Extra alignment tab has been changed to ");
  291.                         print_esc("cr");
  292.                         help_align_apply();
  293.                         extra_info(cur_align) = CR_CODE;
  294.                         error();
  295.                 }
  296.         }
  297.         if (extra_info(cur_align) != SPAN_CODE) {
  298.                 unsave();
  299.                 new_save_level(ALIGN_GROUP);
  300.                 if (mode == -HMODE) {
  301.                         adjust_tail = cur_tail;
  302.                         u = hpack(link(head), NATURAL);
  303.                         w = width(u);
  304.                         cur_tail = adjust_tail;
  305.                         adjust_tail = NULL;
  306.                 } else {
  307.                         u = vpackage(link(head), NATURAL, 0L);
  308.                         w = height(u);
  309.                 }
  310.                 n = MIN_QUARTERWORD;
  311.                 if (cur_span != cur_align) {
  312.                         q = cur_span;
  313.                         do      {
  314.                                 incr(n);
  315.                                 q = link(link(q));
  316.                         } while (q != cur_align);
  317.                         if (n > MAX_QUARTERWORD)
  318.                                 confusion("256 spans");
  319.                         q = cur_span;
  320.                         while (link(info(q)) < n)
  321.                                 q = info(q);
  322.                         if (link(info(q)) > n) {
  323.                                 s = get_node(SPAN_NODE_SIZE);
  324.                                 info(s) = info(q);
  325.                                 link(s) = n;
  326.                                 info(q) = s;
  327.                                 width(s) = w;
  328.                         } else if (width(info(q)) < w)
  329.                                 width(info(q)) = w;
  330.                 } else if (w > width(cur_align))
  331.                         width(cur_align) = w;
  332.                 type(u) = UNSET_NODE;
  333.                 span_count(u) = n;
  334.                 get_stretch_order();
  335.                 glue_order(u) = o;
  336.                 glue_stretch(u) = total_stretch[o];
  337.                 get_shrink_order();
  338.                 glue_sign(u) = o;
  339.                 glue_shrink(u) = total_shrink[o];
  340.                 pop_nest();
  341.                 link(tail) = u;
  342.                 tail = u;
  343.                 tail_append(new_glue(glue_ptr(link(cur_align))));
  344.                 subtype(tail) = TAB_SKIP_CODE + 1;
  345.                 if (extra_info(cur_align) >= CR_CODE)
  346.                         return TRUE;
  347.                 init_span(p);
  348.         }
  349.         align_state = 1000000;
  350.         get_nbx_token();
  351.         cur_align = p;
  352.         init_col();
  353.         return FALSE;
  354. }
  355.  
  356. fin_row ()
  357. {
  358.         ptr             p;
  359.  
  360.         if (mode == -HMODE) {
  361.                 p = hpack(link(head), NATURAL);
  362.                 pop_nest();
  363.                 append_to_vlist(p);
  364.                 if(cur_head != cur_tail) {
  365.                         link(tail) = link(cur_head);
  366.                         tail = cur_tail;
  367.                 }
  368.         } else {
  369.                 p = vpack(link(head), NATURAL);
  370.                 pop_nest();
  371.                 link(tail) = p;
  372.                 tail = p;
  373.                 space_factor = 1000;
  374.         }
  375.         type(p) = UNSET_NODE;
  376.         glue_stretch(p) = 0;
  377.         if (every_cr != NULL)
  378.                 begin_token_list(every_cr, EVERY_CR_TEXT);
  379.         align_peek();
  380. }
  381.  
  382. fin_align ()
  383. {
  384.         hword   n;
  385.         scal    o;
  386.         ptr             p;
  387.         ptr             q;
  388.         ptr             r;
  389.         ptr             s;
  390.         scal    t;
  391.         ptr             u;
  392.         ptr             v;
  393.         scal    w;
  394.         scal    rule_save;
  395.  
  396.         if (cur_group != ALIGN_GROUP)
  397.                 confusion("align1");
  398.         unsave();
  399.         if (cur_group != ALIGN_GROUP)
  400.                 confusion("align0");
  401.         unsave();
  402.         if (nest[nest_ptr - 1].mode_field == MMODE)
  403.                 o = display_indent;
  404.         else o = 0;
  405.         q = link(preamble);
  406.         do {
  407.                 flush_list((ptr) u_part(q));
  408.                 flush_list((ptr) v_part(q));
  409.                 p = link(link(q));
  410.                 if (width(q) == NULL_FLAG) {
  411.                         width(q) = 0;
  412.                         r = link(q);
  413.                         s = glue_ptr(r);
  414.                         if (s != zero_glue) {
  415.                                 add_glue_ref(zero_glue);
  416.                                 delete_glue_ref(s);
  417.                                 glue_ptr(r) = zero_glue;
  418.                         }
  419.                 }
  420.                 if (info(q) != end_span) {
  421.                         t = width(q) + width(glue_ptr(link(q)));
  422.                         r = info(q);
  423.                         s = end_span;
  424.                         info(s) = p;
  425.                         n = MIN_QUARTERWORD + 1;
  426.                         do {    
  427.                                 width(r) -= t;
  428.                                 u = info(r);
  429.                                 while (link(r) > n) {
  430.                                         s = info(s);
  431.                                         n = link(info(s)) + 1;
  432.                                 }
  433.                                 if (link(r) < n) {
  434.                                         info(r) = info(s);
  435.                                         info(s) = r;
  436.                                         decr(link(r));
  437.                                         s = r;
  438.                                 } else {
  439.                                         if (width(r) > width(info(s)))
  440.                                                 width(info(s)) = width(r);
  441.                                         free_node(r, SPAN_NODE_SIZE);
  442.                                 }
  443.                                 r = u;
  444.                         } while (r != end_span);
  445.                 }
  446.                 type(q) = UNSET_NODE;
  447.                 span_count(q) = MIN_QUARTERWORD;
  448.                 height(q) = 0;
  449.                 depth(q) = 0;
  450.                 glue_order(q) = NORMAL;
  451.                 glue_sign(q) = NORMAL;
  452.                 glue_stretch(q) = 0;
  453.                 glue_shrink(q) = 0;
  454.                 q = p;
  455.         } while (q != NULL);
  456.         save_ptr -= 2;
  457.         pack_begin_line = -mode_line;
  458.         if (mode == -VMODE) {
  459.                 rule_save = overfull_rule;
  460.                 overfull_rule = 0;
  461.                 p = hpack(preamble, saved(1), (int) saved(0));
  462.                 overfull_rule = rule_save;
  463.         } else {
  464.                 q = link(preamble);
  465.                 do      {
  466.                         height(q) = width(q);
  467.                         width(q) = 0;
  468.                         q = link(link(q));
  469.                 } while (q != NULL);
  470.                 p = vpackage(preamble, saved(1), (int) saved(0), MAX_DIMEN);
  471.                 q = link(preamble);
  472.                 do      {
  473.                         width(q) = height(q);
  474.                         height(q) = 0;
  475.                         q = link(link(q));
  476.                 } while (q != NULL);
  477.         }
  478.         pack_begin_line = 0;
  479.         for (q = link(head), s = head; q != NULL; s = q, q = link(q)) {/*DIFF*/
  480.                 if (type(q) == UNSET_NODE) {
  481.                         if (mode == -VMODE) {
  482.                                 type(q) = HLIST_NODE;
  483.                                 width(q) = width(p);
  484.                         } else {
  485.                                 type(q) = VLIST_NODE;
  486.                                 height(q) = height(p);
  487.                         }
  488.                         glue_order(q) = glue_order(p);
  489.                         glue_sign(q) = glue_sign(p);
  490.                         glue_set(q) = glue_set(p);
  491.                         shift_amount(q) = o;
  492.                         r = link(list_ptr(q));
  493.                         s = link(list_ptr(p)); 
  494.                         do      {
  495.                                 n = span_count(r); 
  496.                                 t = width(s);
  497.                                 w = t;
  498.                                 u = hold_head;
  499.                                 while (n > MIN_QUARTERWORD) {
  500.                                         decr(n);
  501.                                         s = link(s);
  502.                                         v = glue_ptr(s);
  503.                                         link(u) = new_glue(v);
  504.                                         u = link(u);
  505.                                         subtype(u) = TAB_SKIP_CODE + 1;
  506.                                         t += width(v);
  507.                                         if (glue_sign(p) == STRETCHING)
  508.                                                 if (stretch_order(v) == glue_order(p))
  509.                                                         t += round(glue_set(p) * stretch(v));
  510.                                         else if (glue_sign(p) == SHRINKING)
  511.                                                 if (shrink_order(v) == glue_order(p))
  512.                                                         t -= round(glue_set(p) * shrink(v));
  513.                                         s = link(s);
  514.                                         link(u) = new_null_box();
  515.                                         u = link(u);
  516.                                         t += width(s);
  517.                                         if (mode == -VMODE)
  518.                                                 width(u) = width(s);
  519.                                         else {
  520.                                                 type(u) = VLIST_NODE;
  521.                                                 height(u) = width(s);
  522.                                         }
  523.                                 }
  524.                                 if (mode == -VMODE) {
  525.                                         height(r) = height(q);
  526.                                         depth(r) = depth(q);
  527.                                         if (t == width(r)) {
  528.                                                 glue_sign(r) = NORMAL;
  529.                                                 glue_order(r) = NORMAL;
  530.                                                 glue_set(r) = 0.0;
  531.                                         } else if (t > width(r)) {
  532.                                                 glue_sign(r) = STRETCHING;
  533.                                                 if (glue_stretch(r) == 0)
  534.                                                         glue_set(r) = 0.0;
  535.                                                 else glue_set(r) =
  536.                                                                 (float) (t - width(r)) / glue_stretch(r);
  537.                                         } else {
  538.                                                 glue_order(r) = glue_sign(r);
  539.                                                 glue_sign(r) = SHRINKING;
  540.                                                 if (glue_shrink(r) == 0)
  541.                                                         glue_set(r) = 0.0;
  542.                                                 else if (glue_order(r) == NORMAL &&
  543.                                                                 width(r) - t > glue_shrink(r))
  544.                                                         glue_set(r) = 1.0;
  545.                                                 else glue_set(r) =
  546.                                                         (float)(width(r) - t) / glue_shrink(r);
  547.                                         }
  548.                                         width(r) = w;
  549.                                         type(r) = HLIST_NODE;
  550.                                 } else {
  551.                                         width(r) = width(q);
  552.                                         if (t == height(r)) {
  553.                                                 glue_sign(r) = NORMAL;
  554.                                                 glue_order(r) = NORMAL;
  555.                                                 glue_set(r) = 0.0;
  556.                                         } else if (t > height(r)) {
  557.                                                 glue_sign(r) = STRETCHING;
  558.                                                 if (glue_stretch(r) == 0)
  559.                                                         glue_set(r) = 0.0;
  560.                                                 else glue_set(r) =      
  561.                                                                 (float) (t - height(r)) / glue_stretch(r);
  562.                                         } else {
  563.                                                 glue_order(r) = glue_sign(r);
  564.                                                 glue_sign(r) = SHRINKING;
  565.                                                 if (glue_shrink(r) == 0)
  566.                                                         glue_set(r) = 0.0;
  567.                                                 else if (glue_order(r) == NORMAL &&
  568.                                                                 height(r) - t > glue_shrink(r))
  569.                                                         glue_set(r) = 1.0;
  570.                                                 else glue_set(r) = 
  571.                                                                 (float) (height(r) - t) / glue_shrink(r);
  572.                                         }
  573.                                         height(r) = w;
  574.                                         type(r) = VLIST_NODE;
  575.                                 } 
  576.                                 shift_amount(r) = 0; 
  577.                                 if (u != hold_head) {
  578.                                         link(u) = link(r);
  579.                                         link(r) = link(hold_head);
  580.                                         r = u;
  581.                                 }
  582.                                 r = link(link(r));
  583.                                 s = link(link(s));
  584.                         } while (r != NULL);
  585.                 } else if (type(q) == RULE_NODE) {
  586.                         if (is_running(width(q)))
  587.                                 width(q) = width(p);
  588.                         if (is_running(height(q)))
  589.                                 height(q) = height(p);
  590.                         if (is_running(depth(q)))
  591.                                 depth(q) = depth(p);
  592.                         if (o != 0) {/*DIFF*/
  593.                                 r = link(q); link(q) = NULL;/*DIFF*/
  594.                                 q = hpack(q, NATURAL);/*DIFF*/
  595.                                 shift_amount(q) = o;/*DIFF*/
  596.                                 link(q) = r; link(s) = q;/*DIFF*/
  597.                         }
  598.                 }
  599.         }
  600.         flush_node_list(p);
  601.         pop_alignment();
  602.         t = aux;
  603.         p = link(head);
  604.         q = tail;
  605.         pop_nest();
  606.         if (mode == MMODE) {
  607.                 do_assignments();
  608.                 if (cur_cmd != MATH_SHIFT) {
  609.                         print_err("Missing $$ inserted");
  610.                         help_display_align();
  611.                         back_error();
  612.                 } else {        
  613.                         get_x_token();
  614.                         if (cur_cmd != MATH_SHIFT) {
  615.                                 print_err("Display math should end with $$");
  616.                                 help_display();
  617.                                 back_error();
  618.                         }
  619.                 }
  620.                 pop_nest();
  621.                 tail_append(new_penalty(pre_display_penalty));
  622.                 tail_append(new_param_glue(ABOVE_DISPLAY_SKIP_CODE));
  623.                 link(tail) = p;
  624.                 if (p != NULL)
  625.                         tail = q;
  626.                 tail_append(new_penalty(post_display_penalty));
  627.                 tail_append(new_param_glue(BELOW_DISPLAY_SKIP_CODE));
  628.                 prev_depth = t;
  629.                 resume_after_display();
  630.         } else {        
  631.                 aux = t;
  632.                 link(tail) = p;
  633.                 if (p != NULL)
  634.                         tail = q;
  635.                 if (mode == VMODE)
  636.                         build_page();
  637.         }
  638. }
  639.  
  640. /*
  641.  *      Help text
  642.  */
  643.  
  644. help_display_align ()
  645. {
  646.         help3("Displays can use special alignments (like \\eqalignno)",
  647.         "only if nothing but the alignment itself is between $$'s.",
  648.         "So I've deleted the formulas that preceded this alignment.");
  649. }
  650.  
  651. help_preamble_missing ()
  652. {
  653.         help3("There should be exactly one # between &'s, when an",
  654.         "\\halign or \\valign is being set up. In this case you had",
  655.         "none, so I've put one in; maybe that will work.");
  656. }
  657.  
  658. help_preamble_many ()
  659. {
  660.         help3("There should be exactly one # between &'s, when an",
  661.         "\\halign or \\valign is being set up. In this case you had",
  662.         "more than one, so I'm ignoring all but the first.");
  663. }
  664.  
  665. help_align_apply ()
  666. {
  667.         help3("You have given more \\span or & marks than there were",
  668.         "in the preamble to the \\halign or \\valign now in progress.",
  669.         "So I'll assume that you meant to type \\cr instead.");
  670. }
  671.  
  672. help_display ()
  673. {
  674.         help2("The `$' that I just saw supposedly matches a previous `$$'.",
  675.         "So I shall assume that you typed `$$' both times.");
  676. }
  677.